package com.xinzhidi.common.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池
 *
 * @author cx
 * @date 2023-09-21
 **/
@Component
public class ThreadPoolUtil {

    @Value("${common_service.core_pool_size}")
    private int commonTPCorePoolSize;
    @Value("${common_service.maximum_pool_size}")
    private int commonTPMaximumPoolSize;
    @Value("${common_service.keep_alive_time}")
    private int commonTPKeepAliveTime;

    /**
     * 公用线程池
     */
    public static final String COMMON_THREAD_POOL = "commonThread";

    /**
     * 用来装线程池
     */
    private final Map<String, ThreadPoolExecutor> threadPoolFactory = new HashMap<>();

    /**
     * @author cx
     * @date 2023/09/21 10:13
     * @description initThreadPool
     * 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行，并且只会被服务器执行一次。
     * PostConstruct在构造函数之后执行，init（）方法之前执行。
     * PreDestroy（）方法在destroy（）方法执行之后执行
     */
    @PostConstruct
    private void initThreadPool() {
        // 核心线程5，最大线程20，线程空闲等待时间10秒，有界队列512,任务队列占满时拒绝策略：抛出RejectedExecutionException，
        // 线程工厂指定线程优先级和线程名称
        //创建公共线程池
        ThreadPoolExecutor commonThreadPool = new ThreadPoolExecutor(commonTPCorePoolSize, commonTPMaximumPoolSize,
                commonTPKeepAliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue<>(512),
                Thread::new, new ThreadPoolExecutor.AbortPolicy());
        threadPoolFactory.put(COMMON_THREAD_POOL, commonThreadPool);
    }

    /**
     * 根据不同的消息类型，得到不同的线程池
     *
     * @param keyType key类型
     * @return java.util.concurrent.ThreadPoolExecutor
     * @author zhangyy
     */
    public ThreadPoolExecutor getThreadPoolByType(String keyType) {
        return threadPoolFactory.get(keyType);
    }

    /**
     * @return java.util.concurrent.ThreadPoolExecutor
     * @author cx
     * @date 2023/09/21 16:46
     * @description 获取默认的线程池
     */
    public ThreadPoolExecutor getThreadPoolByDefault() {
        return threadPoolFactory.get(COMMON_THREAD_POOL);
    }

}
